//
//  iExpenseAppDelegate.m
//  iExpense
//
//  Created by WU, Zhenyu on 7/1/09.
//  Copyright National Instruments 2009. All rights reserved.
//

#import "iExpenseAppDelegate.h"
#import "ExpenseViewController.h"
#import "Type.h"
#import "Payment.h"
#import "Currency.h"
#import "Category.h"
#import "Setting.h"


@implementation iExpenseAppDelegate

@synthesize window;
@synthesize rootTabBarController;
@synthesize expenseNavController;



#pragma mark -
#pragma mark Application lifecycle

- (void)applicationDidFinishLaunching:(UIApplication *)application {    
    ExpenseViewController *expenseViewController = (ExpenseViewController*)[expenseNavController topViewController];
	expenseViewController.managedObjectContext = self.managedObjectContext;
	
    // Override point for customization after app launch    
	NSFetchRequest		*requeset = [[NSFetchRequest alloc] init];
	NSEntityDescription *entity	  = [NSEntityDescription entityForName:@"Setting"
												inManagedObjectContext:self.managedObjectContext];
	[requeset setEntity:entity];
	NSError *error;
	NSMutableArray *fetchedResults = [[self.managedObjectContext executeFetchRequest: requeset
									  error:&error] mutableCopy];
	if(fetchedResults == nil) {
		assert(0);
	} else if([fetchedResults count] == 0) {
		
		NSManagedObjectContext *addingContext = [[NSManagedObjectContext alloc] init];
		
		[addingContext setPersistentStoreCoordinator:[self.managedObjectContext persistentStoreCoordinator]];
		
		// Set default types
		Type *typePersonal = (Type *)[[NSManagedObject alloc] 
									  initWithEntity:[[self.managedObjectModel entitiesByName] objectForKey:@"Type"]
									  insertIntoManagedObjectContext:addingContext];
		
		Type *typeBusiness = (Type *)[[NSManagedObject alloc] 
									  initWithEntity:[[self.managedObjectModel entitiesByName] objectForKey:@"Type"]
									  insertIntoManagedObjectContext:addingContext];
		
		NSString *typePersonalName = [[NSString alloc] initWithString:@"Personal"];
		NSString *typeBusinessName = [[NSString alloc] initWithString:@"Business"];
		typePersonal.Name = typePersonalName;
		typeBusiness.Name = typeBusinessName;
		
		// Set default payments
		
		Payment *credit = (Payment *)(Type *)[[NSManagedObject alloc] 
											  initWithEntity:[[self.managedObjectModel entitiesByName] objectForKey:@"Payment"]
											  insertIntoManagedObjectContext:addingContext];

		Payment *cash = (Payment *)[[NSManagedObject alloc] 
									initWithEntity:[[self.managedObjectModel entitiesByName] objectForKey:@"Payment"]
									insertIntoManagedObjectContext:addingContext];
		NSString *creditName = [[NSString alloc] initWithString:@"Credit Card"];
		NSString *cashName = [[NSString alloc] initWithString:@"Cash"];
		credit.Name = creditName;
		cash.Name = cashName;
		
		Currency *rmb = (Currency *)[[NSManagedObject alloc] 
									 initWithEntity:[[self.managedObjectModel entitiesByName] objectForKey:@"Currency"]
									 insertIntoManagedObjectContext:addingContext];
		Currency *usd = (Currency *)[[NSManagedObject alloc] 
									 initWithEntity:[[self.managedObjectModel entitiesByName] objectForKey:@"Currency"]
									 insertIntoManagedObjectContext:addingContext];
		Currency *jpy = (Currency *)[[NSManagedObject alloc] 
									 initWithEntity:[[self.managedObjectModel entitiesByName] objectForKey:@"Currency"]
									 insertIntoManagedObjectContext:addingContext];
		Currency *eur = (Currency *)[[NSManagedObject alloc] 
									 initWithEntity:[[self.managedObjectModel entitiesByName] objectForKey:@"Currency"]
									 insertIntoManagedObjectContext:addingContext];
		NSString *rmbName = [[NSString alloc] initWithString:@"RMB"];
		NSString *usdName = [[NSString alloc] initWithString:@"USD"];
		NSString *jpyName = [[NSString alloc] initWithString:@"JPY"];
		NSString *eurName = [[NSString alloc] initWithString:@"EUR"];
		NSString *rmbSymbol = [[NSString alloc] initWithString:@"￥"];
		NSString *usdSymbol = [[NSString alloc] initWithString:@"$"];
		NSString *jpySymbol = [[NSString alloc] initWithString:@"￥"];
		NSString *eurSymbol = [[NSString alloc] initWithString:@"€"];
		rmb.Name = rmbName;
		usd.Name = usdName;
		jpy.Name = jpyName;
		eur.Name = eurName;
		rmb.Symbol = rmbSymbol;
		usd.Symbol = usdSymbol;
		jpy.Symbol = jpySymbol;
		eur.Symbol = eurSymbol;
		
		Category *other = (Category *)[[NSManagedObject alloc] 
									   initWithEntity:[[self.managedObjectModel entitiesByName] objectForKey:@"Category"]
									   insertIntoManagedObjectContext:addingContext];
		Category *meal = (Category *)[[NSManagedObject alloc]
									  initWithEntity:[[self.managedObjectModel entitiesByName] objectForKey:@"Category"]
									  insertIntoManagedObjectContext:addingContext];
		Category *transport = (Category *)[[NSManagedObject alloc]
										   initWithEntity:[[self.managedObjectModel entitiesByName] objectForKey:@"Category"]
										   insertIntoManagedObjectContext:addingContext];
		NSString *otherName = [[NSString alloc] initWithString:@"Other"];
		NSString *mealName = [[NSString alloc] initWithString:@"Meal"];
		NSString *transportName = [[NSString alloc] initWithString:@"Transport"];
		other.Name  = otherName;
		meal.Name = mealName;
		transport.Name = transportName;

		Setting *newSetting = (Setting *)[[NSManagedObject alloc]
										initWithEntity:[[self.managedObjectModel entitiesByName] objectForKey:@"Setting"]
										insertIntoManagedObjectContext:addingContext];
		
		newSetting.Type = typePersonal;
		newSetting.Currency = usd;
		newSetting.Payment = cash;
		newSetting.Category = other;
		NSNumber *firstIdentity = [[NSNumber alloc] initWithLongLong:0];
		newSetting.LastIdentity = firstIdentity;

		if (![addingContext save:&error]) {
			// Update to handle the error appropriately.
			NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
			exit(-1);  // Fail
		}
		[typePersonalName release];
		[typeBusinessName release];
		[typePersonal release];
		[typeBusiness release];
		[creditName release];
		[cashName release];
		[credit release];
		[cash release];
		[rmbName release];
		[usdName release];
		[jpyName release];
		[eurName release];
		[rmbSymbol release];
		[usdSymbol release];
		[jpySymbol release];
		[eurSymbol release];
		[rmb release];
		[usd release];
		[jpy release];
		[eur release];
		[other release];
		[meal release];
		[transport release];
		[otherName release];
		[mealName release];
		[transportName release];
		[firstIdentity release];
		[addingContext release];


	}

	[fetchedResults release];
	[requeset release];
	[window addSubview:rootTabBarController.view];
	[window makeKeyAndVisible];
}

/**
 applicationWillTerminate: saves changes in the application's managed object context before the application terminates.
 */
- (void)applicationWillTerminate:(UIApplication *)application {
	
    NSError *error;
    if (managedObjectContext != nil) {
        if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error]) {
			// Handle error
			NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
			exit(-1);  // Fail
        } 
    }
}


#pragma mark -
#pragma mark Saving

/**
 Performs the save action for the application, which is to send the save:
 message to the application's managed object context.
 */
- (IBAction)saveAction:(id)sender {
	
    NSError *error;
    if (![[self managedObjectContext] save:&error]) {
		// Handle error
		NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
		exit(-1);  // Fail
    }
}


#pragma mark -
#pragma mark Core Data stack

/**
 Returns the managed object context for the application.
 If the context doesn't already exist, it is created and bound to the persistent store coordinator for the application.
 */
- (NSManagedObjectContext *) managedObjectContext {
	
    if (managedObjectContext != nil) {
        return managedObjectContext;
    }
	
    NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
    if (coordinator != nil) {
        managedObjectContext = [[NSManagedObjectContext alloc] init];
        [managedObjectContext setPersistentStoreCoordinator: coordinator];
    }
    return managedObjectContext;
}


/**
 Returns the managed object model for the application.
 If the model doesn't already exist, it is created by merging all of the models found in the application bundle.
 */
- (NSManagedObjectModel *)managedObjectModel {
	
    if (managedObjectModel != nil) {
        return managedObjectModel;
    }
    managedObjectModel = [[NSManagedObjectModel mergedModelFromBundles:nil] retain];    
    return managedObjectModel;
}


/**
 Returns the persistent store coordinator for the application.
 If the coordinator doesn't already exist, it is created and the application's store added to it.
 */
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
	
    if (persistentStoreCoordinator != nil) {
        return persistentStoreCoordinator;
    }
	
    NSURL *storeUrl = [NSURL fileURLWithPath: [[self applicationDocumentsDirectory] stringByAppendingPathComponent: @"iExpense.sqlite"]];
	
	NSError *error;
    persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: [self managedObjectModel]];
    if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:nil error:&error]) {
        // Handle error
    }    
	
    return persistentStoreCoordinator;
}


#pragma mark -
#pragma mark Application's documents directory

/**
 Returns the path to the application's documents directory.
 */
- (NSString *)applicationDocumentsDirectory {
	
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *basePath = ([paths count] > 0) ? [paths objectAtIndex:0] : nil;
    return basePath;
}


#pragma mark -
#pragma mark Memory management

- (void)dealloc {
	
    [managedObjectContext release];
    [managedObjectModel release];
    [persistentStoreCoordinator release];
	
	[expenseNavController release];
	[rootTabBarController release];
	[window release];
	[super dealloc];
}


@end

